†IPFSを実行しながら学んでいく3 ~不変性~ †
††学んだ内容をメモメモ††
IPFSのコマンドラインツールを使いながらIPFSに関して基本的なことを色々と学んでいこうとしています。
前回はIPFSのコンテンツを固定する方法(永続性)について試してみました。
今回はデータの更新に関して試していこうと思います。
データの更新を試す
IPFSでは、IPFSネットワークに追加されると、そのファイルのコンテンツは、ファイルのコンテンツ識別子(CID)を変更せずに変更することができない となっています。
$ echo "Hello, IPFS." > hello $ ipfs add hello added QmTp4UwYBop1Qi4MGmHhwJ4VPDZVNpFfmrRVDqU9texC6H hello $ ipfs cat QmTp4UwYBop1Qi4MGmHhwJ4VPDZVNpFfmrRVDqU9texC6H Hello, IPFS.
helloというファイルを追加しましたが、このファイルを更新してみましょう。
$ echo "犬、猫" >> hello $ cat hello Hello, IPFS. 犬、猫
このファイルをipfsに追加すると,
$ ipfs add hello added QmZb9UKiX8gAzfo5ZQbwUSaNFe7e1FPAtQgrhud4teHX4q hello
先ほどと内容が違うのでCIDが変更されました。これが不変性の機能です。
$ ipfs cat QmTp4UwYBop1Qi4MGmHhwJ4VPDZVNpFfmrRVDqU9texC6H Hello, IPFS $ ipfs cat QmZb9UKiX8gAzfo5ZQbwUSaNFe7e1FPAtQgrhud4teHX4q Hello, IPFS. 犬、猫
ローカルファイル上では同じ名前のコンテンツですが、IPFS上では別のコンテンツになります。 変更する必要のないデータを保存する時に最適なものとなっています。
更新が必要なものはどう?
Webサイトなど、更新が必要なコンテンツはIPFSでどうすればいいだろう? という疑問が出てきます。 IPFSにWebサイトのコンテンツをアップロードしたら、提供しているサーバーが使用不能になっても、IPFSのネットワークからユーザーは影響を受けずにページを取得できますが、 ページを更新するたびにCIDが変更されると毎回ユーザーに新しいリンクを伝えないといけなくなります。
上記で試したファイルだと、
/ipfs/QmTp4UwYBop1Qi4MGmHhwJ4VPDZVNpFfmrRVDqU9texC6H
から /ipfs/QmZb9UKiX8gAzfo5ZQbwUSaNFe7e1FPAtQgrhud4teHX4q
に変更。
こういったことを解決するためには、IPNS(InterPlantery Naming Service)という更新可能なアドレスを作成する仕組みを使うことができます。
イメージ)
+--------+ +---------+ +----------+ | User | ---> | Pointer | | QmTp4... | +--------+ +---------+ +----------+ | | +----------+ + --------> | QmZb9... | +----------+
ユーザーはPointer
にアクセスすると、更新されたコンテンツを参照することができます
例)
/ipns/QmSrPmbaUKA3ZodhzPWZnpFgcPMFWF4QsxXbkWfEptTBJd
IPNSを使用すると、CIDを直接扱うという面倒な作業からユーザーを解放できるという利点があります。
IPNSを使ってみる
ファイル作成
IPNSに公開するhtmlファイルを作成します
$ vi index.html
index.htmlの内容は以下のようにしました
<html> <body> <p>こんにちは、世界</p> </body> </html>
IPFSに追加
作成したHTMLをIPFSに追加します。
$ ipfs add index.html added QmYfYPRZLjKzj9SqpCFxzdiyop9QXs69LzCLxtprVPKQnb index.html
確認
ipfs cat QmYfYPRZLjKzj9SqpCFxzdiyop9QXs69LzCLxtprVPKQnb <html> <body> <p>こんにちは、世界</p> </body> </html>
IPFSデーモンを起動
次のコマンドでデーモンを起動します
$ ipfs daemon go-ipfs version: 0.13.0 Repo version: 12 System version: amd64/linux Golang version: go1.18.3 2022/07/05 02:57:17 failed to sufficiently increase receive buffer size (was: 208 kiB, wanted: 2048 kiB, got: 416 kiB). See https://github.com/lucas -clemente/quic-go/wiki/UDP-Receive-Buffer-Size for details. Swarm listening on /ip4/127.0.0.1/tcp/4001 Swarm listening on /ip4/127.0.0.1/udp/4001/quic Swarm listening on /ip4/172.31.4.63/tcp/4001 Swarm listening on /ip4/172.31.4.63/udp/4001/quic Swarm listening on /ip6/::1/tcp/4001 Swarm listening on /ip6/::1/udp/4001/quic Swarm listening on /p2p-circuit Swarm announcing /ip4/127.0.0.1/tcp/4001 Swarm announcing /ip4/127.0.0.1/udp/4001/quic Swarm announcing /ip4/13.230.148.139/udp/4001/quic Swarm announcing /ip4/172.31.4.63/tcp/4001 Swarm announcing /ip4/172.31.4.63/udp/4001/quic Swarm announcing /ip6/::1/tcp/4001 Swarm announcing /ip6/::1/udp/4001/quic API server listening on /ip4/127.0.0.1/tcp/5001 WebUI: http://127.0.0.1:5001/webui Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080 Daemon is ready
上記のように表示されていると起動しています。
CIDをIPNSに公開
作成したHTMLのハッシュをIPNSに公開します。
ipfs name publish <<コンテンツのCID>>
$ ipfs name publish /ipfs/QmYfYPRZLjKzj9SqpCFxzdiyop9QXs69LzCLxtprVPKQnb Published to k51qzi5uqu5dic7r0ly7l3d65nsfp7gbbmwv6cj0216kx9fgsfykzdnsdmrdn6: /ipfs/QmYfYPRZLjKzj9SqpCFxzdiyop9QXs69LzCLxtprVPKQnb
少しの時間経過後、公開されます。
k51qz~~~
というのが実行しているIPFSの公開鍵またはIPNS名となっていて、ファイルが更新されてもこのキーを使用して引き続きファイルにアクセスできます
Gatewayを通じてファイルにアクセスしてみる
以下のコマンドを利用してIPNSにアクセスしてみます
ローカルでdaemonを立ち上げましたが、出力に
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
と表示されていました。
Gatewayへのアクセスは http://127.0.0.1:8080
です。
$ curl 127.0.0.1:8080/ipns/k51qzi5uqu5dic7r0ly7l3d65nsfp7gbbmwv6cj0216kx9fgsfykzdnsdmrdn6 <html> <body> <p>こんにちは、世界</p> </body> </html>
と、追加したファイルの内容が返ってきました。
ファイルを更新
index.htmlに何か変更を加えた後、再度publishします。
cat index.html <html> <body> <p>こんにちは、世界</p> <h1>This is Headline level 1</h1> </body> </html>
$ ipfs add index.html added QmVgGMEeMtzjEGB1QQ3uqncvBTT4TMmMfwAkBkLzNgFdNN index.html $ ipfs cat QmVgGMEeMtzjEGB1QQ3uqncvBTT4TMmMfwAkBkLzNgFdNN
CIDが変更されました
IPNSを更新
更新したファイルのCIDをpublishします
$ ipfs name publish QmVgGMEeMtzjEGB1QQ3uqncvBTT4TMmMfwAkBkLzNgFdNN Published to k51qzi5uqu5dic7r0ly7l3d65nsfp7gbbmwv6cj0216kx9fgsfykzdnsdmrdn6: /ipfs/QmVgGMEeMtzjEGB1QQ3uqncvBTT4TMmMfwAkBkLzNgFdNN
先ほどと同じk51qz~~~
というキーが返ってきました
Gatewayを通じてファイルにアクセスしてみる
では先ほどと同じようにgatewayからアクセスしてみます
$ curl 127.0.0.1:8080/ipns/k51qzi5uqu5dic7r0ly7l3d65nsfp7gbbmwv6cj0216kx9fgsfykzdnsdmrdn6 <html> <body> <p>こんにちは、世界</p> <h1>This is Headline level 1</h1> </body> </html>
すると、追加した内容が表示されました
キーに関連付けられているファイルのCIDを調べる
ipfs name resolve <<キー>>
で、紐づいたCIDを確認できます
$ ipfs name resolve k51qzi5uqu5dic7r0ly7l3d65nsfp7gbbmwv6cj0216kx9fgsfykzdnsdmrdn6 /ipfs/QmVgGMEeMtzjEGB1QQ3uqncvBTT4TMmMfwAkBkLzNgFdNN
QmVgG~~~
というのが現在のCIDで、先ほど更新してIPFSに追加したものと一致しました。
コンテンツの不変性は保ちつつ、アクセスするときは常に同じアドレスを使用できるようにIPNSを試してみました。 更新が必要なコンテンツを扱う場合、この考えは役に立ちそうです。
また、IPFSで可変アドレスを作成する方法はIPNSだけでなく、DNSLink というのも使えるようですので次回試してみようと思います